package com.example.util;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 简化的JWT工具类 - 不依赖Redis
 */
@Slf4j
@Component
public class SimpleJwtTokenUtil {

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration:86400}") // 24小时
    private Long expiration;

    /**
     * 获取签名密钥
     */
    private SecretKey getSigningKey() {
        return Keys.hmacShaKeyFor(secret.getBytes());
    }

    /**
     * 生成访问令牌
     */
    public String generateAccessToken(String username, String userType, Map<String, Object> claims) {
        Map<String, Object> tokenClaims = new HashMap<>();
        if (claims != null) {
            tokenClaims.putAll(claims);
        }
        tokenClaims.put("userType", userType);
        tokenClaims.put("tokenType", "access");
        
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + expiration * 1000);
        String tokenId = generateTokenId();
        
        String token = Jwts.builder()
                .setClaims(tokenClaims)
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .setIssuer("laundry-system")
                .setId(tokenId)
                .signWith(getSigningKey(), SignatureAlgorithm.HS512)
                .compact();
        
        return token;
    }

    /**
     * 从token中获取用户名
     */
    public String getUsernameFromToken(String token) {
        try {
            Claims claims = getClaimsFromToken(token);
            return claims.getSubject();
        } catch (Exception e) {
            log.error("获取用户名失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 从token中获取用户类型
     */
    public String getUserTypeFromToken(String token) {
        try {
            Claims claims = getClaimsFromToken(token);
            return (String) claims.get("userType");
        } catch (Exception e) {
            log.error("获取用户类型失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 从token中获取声明
     */
    public Claims getClaimsFromToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     * 验证token
     */
    public Boolean validateToken(String token) {
        try {
            // 1. 解析token
            Claims claims = getClaimsFromToken(token);
            
            // 2. 检查token是否过期
            if (isTokenExpired(token)) {
                log.warn("Token已过期: {}", claims.getSubject());
                return false;
            }
            
            // 3. 检查签发者
            if (!"laundry-system".equals(claims.getIssuer())) {
                log.warn("Token签发者不正确: {}", claims.getIssuer());
                return false;
            }
            
            return true;
        } catch (SecurityException e) {
            log.error("Token签名验证失败: {}", e.getMessage());
        } catch (MalformedJwtException e) {
            log.error("Token格式错误: {}", e.getMessage());
        } catch (ExpiredJwtException e) {
            log.error("Token已过期: {}", e.getMessage());
        } catch (UnsupportedJwtException e) {
            log.error("不支持的Token: {}", e.getMessage());
        } catch (IllegalArgumentException e) {
            log.error("Token参数错误: {}", e.getMessage());
        } catch (Exception e) {
            log.error("Token验证失败: {}", e.getMessage());
        }
        return false;
    }

    /**
     * 检查token是否过期
     */
    public Boolean isTokenExpired(String token) {
        try {
            Claims claims = getClaimsFromToken(token);
            Date expiration = claims.getExpiration();
            return expiration.before(new Date());
        } catch (Exception e) {
            return true;
        }
    }

    /**
     * 生成token ID
     */
    private String generateTokenId() {
        return java.util.UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 检查token是否即将过期（30分钟内）
     */
    public Boolean isTokenExpiringSoon(String token) {
        try {
            Claims claims = getClaimsFromToken(token);
            Date expiration = claims.getExpiration();
            Date now = new Date();
            long timeDiff = expiration.getTime() - now.getTime();
            return timeDiff < 30 * 60 * 1000; // 30分钟
        } catch (Exception e) {
            return true;
        }
    }

    /**
     * 获取token剩余有效时间（秒）
     */
    public Long getTokenRemainingTime(String token) {
        try {
            Claims claims = getClaimsFromToken(token);
            Date expiration = claims.getExpiration();
            Date now = new Date();
            return (expiration.getTime() - now.getTime()) / 1000;
        } catch (Exception e) {
            return 0L;
        }
    }
}
